<template>
  <div class="container">
    <div class="app-container">
      <el-row :gutter="12">
        <el-col>
          <el-card shadow="always">
            <!-- 添加角色 -->
            <el-button type="primary" @click="showDialog = true"
              >添加角色</el-button
            >
            <!-- 内容表格 -->
            <el-table :data="roleList" style="width: 100%">
              <el-table-column prop="name" label="角色" width="180">
                <template #default="{ row }">
                  <el-input
                    v-if="row.isEdit"
                    v-model="row.temp.name"
                  ></el-input>
                  <span v-else>{{ row.name }}</span>
                </template>
              </el-table-column>
              <el-table-column prop="state" label="启用" width="180">
                <template #default="{ row }">
                  <el-switch
                    v-if="row.isEdit"
                    v-model="row.temp.state"
                    active-color="#13ce66"
                    inactive-color="#ff4949"
                    :active-value="1"
                    :inactive-value="0"
                  >
                  </el-switch>
                  <span v-else>{{
                    row.state === 1 ? "已启用" : "未启用"
                  }}</span>
                </template>
              </el-table-column>
              <el-table-column prop="description" label="描述">
                <template #default="{ row }">
                  <el-input
                    v-if="row.isEdit"
                    v-model="row.temp.description"
                    type="textarea"
                  ></el-input>
                  <span v-else>{{ row.description }}</span>
                </template>
              </el-table-column>
              <el-table-column prop="address" label="操作">
                <template #default="{ row }">
                  <template v-if="row.isEdit">
                    <el-button type="primary" @click="updataRow(row)"
                      >确认</el-button
                    >
                    <el-button @click="row.isEdit = false">取消</el-button>
                  </template>
                  <template v-else>
                    <el-button type="text" @click="allotPermission(row.id)"
                      >分配权限</el-button
                    >
                    <el-button
                      type="text"
                      @click="openEdit(row)"
                      style="margin-right: 12px"
                      >编辑</el-button
                    >
                    <el-popconfirm
                      title="这是一段内容确定删除吗？"
                      @confirm="delRow(row.id)"
                    >
                      <el-button type="text" slot="reference">删除</el-button>
                    </el-popconfirm>
                  </template>
                </template>
              </el-table-column>
            </el-table>
            <!-- 底部分页 -->
            <el-row type="flex" justify="center" class="row-bg">
              <!-- page-size el语法, 每页显示条目个数，支持 .sync 修饰符 -->
              <!-- current-page	el语法, 当前页数，支持 .sync 修饰符 -->
              <!-- total	el语法, 总条目数 -->
              <!-- current-change el语法，currentPage 改变时会触发 -->
              <el-pagination
                background
                :current-page="query.page"
                :page-size="query.pagesize"
                layout="prev, pager, next"
                :total="total"
                @current-change="handleCurrentChange"
              >
              </el-pagination>
            </el-row>
          </el-card>
        </el-col>
      </el-row>
    </div>

    <!-- 弹出提示 -->
    <el-dialog
      title="提示"
      :visible.sync="showDialog"
      width="30%"
      @close="cancel"
    >
      <el-form ref="form" :model="form" label-width="80px" :rules="rules">
        <el-form-item label="角色名称" prop="name">
          <el-input v-model="form.name"></el-input>
        </el-form-item>
        <el-form-item label="启用" prop="state">
          <el-switch
            v-model="form.state"
            active-color="#13ce66"
            inactive-color="#ff4949"
            :active-value="1"
            :inactive-value="0"
          >
          </el-switch>
        </el-form-item>
        <el-form-item label="角色描述" prop="description">
          <el-input v-model="form.description" type="textarea"></el-input>
        </el-form-item>
      </el-form>
      <el-row slot="footer" class="dialog-footer" type="flex" justify="center">
        <el-button @click="cancel">取 消</el-button>
        <el-button type="primary" @click="confirm">确 定</el-button>
      </el-row>
    </el-dialog>

    <!-- 分配权限弹层 -->
    <el-dialog
      title="分配权限"
      :visible.sync="showPermissionDialog"
      width="50%"
    >
      <el-tree
        ref="permTree"
        v-loading="loading"
        check-strictly
        :data="permissionData"
        show-checkbox
        node-key="id"
        :default-checked-keys="permIds"
        :props="defaultProps"
      >
      </el-tree>

      <span slot="footer" class="dialog-footer">
        <el-button type="primary" @click="allotPermissionConfirm"
          >确 定</el-button
        >
        <el-button @click="showPermissionDialog = false">取 消</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
// 1. 定制组件的呈现、行为 配置props slots
// 2. 如果在组件上的操作希望得到反馈， 配置events
// 3. 如果在组件外 想使用组件的功能、数据，配置组件的ref，使用ref得到组件的实例
import {
  getRoleList,
  addRoleList,
  updataRoleList,
  delRoleList,
  getRoleDetail,
  assignPerm,
} from "@/api/role";
import { getPermissionList } from "@/api/permission";
import { transListToTreeData } from "@/utils";
export default {
  name: "Role",
  data() {
    return {
      query: {
        page: 1,
        pagesize: 5,
      },
      loading: false,
      roleList: [], // 存储的列表数据
      total: 0, // 总数
      showDialog: false,
      showPermissionDialog: false, // 分配权限弹层
      permissionData: [], // 分配权限  tree状图
      currentRoleId: null, // 点击分配角色传的id
      permIds: [], // 权限id数组
      form: {}, // form 直接提供空对象
      // 响应式数据：数据变化，驱动页面更新
      // const常量 虽然表达数据是不变的常量，但是还可以从内部改某些属性（数组 对象 都可以改内部数据，只是不能重新赋值）
      // Objec.freeze 表达的语义是这个数据冰封起来，不要再动了，vue遇到这样的声明就明白这个数据不会变化更新，那么就不在做getter和setter处理
      rules: Object.freeze({
        name: [{ required: true, message: "名字不能为空", trigger: "blur" }],
        description: [
          { required: true, message: "描述不能为空", trigger: "blur" },
        ],
      }),
      defaultProps: {
        children: "children",
        label: "name",
      },
    };
  },
  created() {
    this.getRoleList();
  },
  methods: {
    async getRoleList() {
      const { rows, total } = await getRoleList(this.query);
      // console.log('11111', ret);
      // console.log('1111',rows);
      this.roleList = rows.map((item) => {
        item.isEdit = false;
        item.temp = {}; // 缓存 编辑时的临时数据
        return item;
      });
      this.total = total;
    },
    handleCurrentChange(page) {
      // console.log("最新页码：", page);
      this.query.page = page;
      this.getRoleList();
    },
    cancel() {
      this.$refs.form.resetFields();
      this.showDialog = false;
    },
    async confirm() {
      const isOK = await this.$refs.form.validate().catch((err) => err);
      if (!isOK) return;
      await addRoleList(this.form);
      this.$message({
        message: "添加角色成功",
        type: "success",
      });
      this.cancel();
      this.getRoleList();
    },
    openEdit(row) {
      row.temp = {
        id: row.id,
        name: row.name,
        state: row.state,
        description: row.description,
      };
      row.isEdit = true;
    },

    async updataRow(row) {
      // 1. 校验表单项填写是否合法，不合法阻止
      if (!row.temp.name || !row.temp.description) {
        return this.$message.error("角色和描述不能为空！");
      }
      try {
        // 2. 合法的话调接口更新数据
        await updataRoleList(row.temp);
        // 3. 提示更新的结果（成功 & 失败）
        this.$message({
          message: "更新角色成功",
          type: "success",
        });
        // 4. 前端同步更新数据（重新调接口 或者 前端直接用最新的数据更新界面）
        // 5. 关闭表单 清空表单项及校验规则
        Object.assign(row, row.temp, { isEdit: false });
      } catch (error) {
        this.$message({
          type: "error",
          message: error ? "错误" : "网络错误",
        });
      }
    },
    async delRow(id) {
      // console.log(111);
      await delRoleList(id);
      this.$message({
        message: "删除成功",
        type: "success",
      });
      if (this.roleList.length === 1 && this.query.page > 1) this.query.page--;
      this.getRoleList();
    },
    // 分配权限
    async allotPermission(id) {
      this.showPermissionDialog = true;
      this.loading = true;
      this.permissionData = transListToTreeData(await getPermissionList(), 0);
      this.currentRoleId = id;
      const { permIds } = await getRoleDetail(id);
      this.permIds = permIds;
      this.loading = false;
    },
    // 分配权限弹层确认按钮
    async allotPermissionConfirm() {
      await assignPerm({
        id: this.currentRoleId,
        permIds: this.$refs.permTree.getCheckedKeys(),
      });
      this.$message.success("角色分配权限成功");
      this.showPermissionDialog = false;
      this.permIds = [];
    },
  },
};
</script>
<style>
.row-bg {
  padding: 10px 0;
  background-color: #f9fafc;
}
</style>
